package com.cipe.cmrs.model;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.cipe.cmrs.util.Util;

/**
 * @author Incepio
 */
@Entity
@Table(name = "userinfo")
@NamedQueries({ @NamedQuery(name = "getUserByLoginNameAndPassword", query = " FROM User u where lower(u.loginName) = ? and u.password = ?") })
public class User extends BaseAuditEntity implements UserDetails {

    public static final String LOGGED_IN_USER_KEY = UsernamePasswordAuthenticationFilter.SPRING_SECURITY_FORM_USERNAME_KEY;
	private static final long	serialVersionUID	= 2050469065293292560L;
	@Transient
	private String				confirmPassword;
	@Column(name = "email")
	private String				email;
	@Column(name = "employeeid")
	private String				employeeId;
    @ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "fieldofficeid")
	private Fieldoffice			fieldoffice;
	@Column(name = "firstname")
	private String				firstName;
	@Column(name = "lastname")
	private String				lastName;
	@Column(name = "loginname")
	private String				loginName;
	@Column(name = "middlename")
	private String				middleName;
	@Transient
	private String				newPassword;
	@Column(name = "password")
	private String				password;
	@Column(name = "phone")
	private String				phone;	
	
	@Basic
	@Column(name="startdate")
	private Timestamp startDate;
	@Basic
	@Column(name="enddate")
	private Timestamp endDate;
	
	public Timestamp getStartDate() {
		return startDate;
	}

	public void setStartDate(Timestamp startDate) {
		this.startDate = startDate;
	}

	public Timestamp getEndDate() {
		return endDate;
	}

	public void setEndDate(Timestamp endDate) {
		this.endDate = endDate;
	}

	private Boolean				inactive;
	// @Column(name = "phoneext")
	// private String phoneExt;
    @ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "regionid")
	private Region				region;
	@Column(name = "statuscode")
	private String				statusCode;
    @ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "usertypeid")
	private Usertype			usertype;
    
    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name="preferenceid")
    private UserPreference userPreference;
    /**
     * List of Roles
     */
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "userrole", joinColumns = { @JoinColumn(name = "userinfoid") }, inverseJoinColumns = @JoinColumn(name = "roleid"))
    private Set<Role> roles;

    @OneToMany(cascade=CascadeType.ALL,mappedBy="user",fetch=FetchType.EAGER)
    private List<Useractionalertschanges> useractionalertschangesList=new ArrayList<Useractionalertschanges>();
    
    @Transient
    private Map<String, Map<String, String>> allowedUiElementsMap;
    
    @Transient
    public Collection<GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> result = new ArrayList<GrantedAuthority>();
        if (roles != null) {
            result.addAll(roles);
        }
        return result;
    }

    @Transient
    public String getUsername() {
        return loginName;
    }

    @Transient
    public boolean isAccountNonExpired() {
        return true;
    }

    @Transient
    public boolean isAccountNonLocked() {
        return true;
    }

    @Transient
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Transient
    public boolean isEnabled() {
        return true;
    }
    
	/**
	 * @return the userPreference
	 */
	public UserPreference getUserPreference() {
		return userPreference;
	}

	/**
	 * @param userPreference the userPreference to set
	 */
	public void setUserPreference(UserPreference userPreference) {
		this.userPreference = userPreference;
	}

    public List<Useractionalertschanges> getUseractionalertschangesList() {
		return useractionalertschangesList;
	}

	public void setUseractionalertschangesList(
			List<Useractionalertschanges> useractionalertschangesList) {
		this.useractionalertschangesList = useractionalertschangesList;
	}

	public String getConfirmPassword() {
		return confirmPassword;
	}

	public String getEmail() {
		return email;
	}

	public String getEmployeeId() {
		return employeeId;
	}

	/**
	 * @return the fieldoffice
	 */
	public Fieldoffice getFieldoffice() {
		return fieldoffice;
	}

	public String getFirstName() {
		return firstName;
	}

	public String getFullName() {
		return Util.concate(new String[] { firstName, lastName }, " ");
	}

	public Boolean getInactive() {
		return inactive;
	}

	public String getLastName() {
		return lastName;
	}

	public String getLoginName() {
		return loginName;
	}

	public String getMiddleName() {
		return middleName;
	}

	public String getNewPassword() {
		return newPassword;
	}

	public String getPassword() {
		return password;
	}

	public String getPhone() {
		return phone;
	}

	/**
	 * @return the region
	 */
	public Region getRegion() {
		return region;
	}

	public String getStatusCode() {
		return statusCode;
	}

	/**
	 * @return the usertype
	 */
	public Usertype getUsertype() {
		return usertype;
	}

	public void setConfirmPassword(String confirmPassword) {
		this.confirmPassword = confirmPassword;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public void setEmployeeId(String employeeId) {
		this.employeeId = employeeId;
	}

	/**
	 * @param fieldoffice
	 *            the fieldoffice to set
	 */
	public void setFieldoffice(Fieldoffice fieldoffice) {
		this.fieldoffice = fieldoffice;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public void setInactive(Boolean inactive) {
		this.inactive = inactive;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public void setLoginName(String loginName) {
		this.loginName = loginName;
	}

	public void setMiddleName(String middleName) {
		this.middleName = middleName;
	}

	public void setNewPassword(String newPassword) {
		this.newPassword = newPassword;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	/**
	 * @param region
	 *            the region to set
	 */
	public void setRegion(Region region) {
		this.region = region;
	}

	public void setStatusCode(String statusCode) {
		this.statusCode = statusCode;
	}

	/**
	 * @param usertype
	 *            the usertype to set
	 */
	public void setUsertype(Usertype usertype) {
		this.usertype = usertype;
	}

    public Set<Role> getRoles() {
        return roles;
    }

    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }

    @Transient
    public List<String> getRoleNames() {
        List<String> roleNames = new ArrayList<String>();
        if (roles != null) {
            for (Role role : roles) {
                roleNames.add(role.getDisplayName());
            }
        }
        return roleNames;
    }

    public Map<String, Map<String, String>> getAllowedUiElementsMap() {
        return allowedUiElementsMap;
    }

    public void setAllowedUiElementsMap(Map<String, Map<String, String>> allowedUiElementsMap) {
        this.allowedUiElementsMap = allowedUiElementsMap;
    }

}
